home *** CD-ROM | disk | FTP | other *** search
/ PCMania 30 / PCMania CD30.iso / pcmania / graf30 / tacs / writetag.c < prev   
C/C++ Source or Header  |  1988-04-27  |  11KB  |  526 lines

  1. /* ------------------------------------------------------------------ */
  2. /*                                      */
  3. /*    Developed by:    Vijayakumar Rangarajan                  */
  4. /*    Name:        writetag.c                      */
  5. /*    Function:    Allows insertion of a new tag into the          */
  6. /*            existing field list/ update of the existing   */
  7. /*            tag value                      */
  8. /* 9/22 Original, backedup as writetag.ins, works with all *.ins      */
  9. /* 10.10 pm with write_tags, and 'far' pointers in write_fields.      */
  10. /*                                      */
  11. /* 9/22                                   */
  12. /* 10.25 New change to support direct file creation with write_tags   */
  13. /*     without prior to write_fields.                   */
  14. /*                                      */
  15. /* ------------------------------------------------------------------ */
  16.  
  17. #include "tifstruc.h"
  18.  
  19. extern    long    set_position();
  20. extern    long    get_cpos();
  21. extern    int    write_data();
  22. extern    int    header_write();
  23. extern    int    header_rewrite();
  24. extern    int    field_data_write();
  25. extern    ifdstrc subfile, strpofst, strpbtcnt;
  26.     void    new_check_tag();
  27. extern    void    init_tif_hdr();
  28. extern    char    tag_273;
  29. extern    char    tag_279;
  30. extern    long    field_data_pos;
  31. extern    long    field_data_endpos;
  32. extern    long    header_fil1_pos;
  33. extern    long    ifdsize;
  34. extern    long    next_val_pos;
  35. extern    short    fields_exist;
  36. extern    short    image_begin;
  37. extern    long    get_tagval();
  38. extern    int    find_type();
  39. extern    short    rewrite_field_data();
  40. extern    int    write_tag_val();
  41. extern    short    field_mem_tab[];
  42. extern    int    tot_tag_num;
  43.  
  44. void build_sbfile_tag();
  45.  
  46. short    field_mem_tab1[256];
  47.  
  48.  
  49.  
  50. static    short    *field_cur_ptr;
  51. static    short    *temp_field_cur_ptr;
  52. static    short    build_tag_mem[6];
  53. static    short    *new_tag_ptr;
  54. static    short    *new_tag_pos;
  55. static    short    new_tag_index;
  56.  
  57. static    unsigned bytsize = 12;         /* tag byte size = 12 */
  58.  
  59. short    *build_one_tag(), find_len(), find_tag_pos(), update_temp_list();
  60.  
  61. int   write_tag(filehndl, fdtype, tagnum, dataptr, length)
  62.  
  63. int    filehndl;
  64. short    fdtype;
  65. short    tagnum;
  66. short far  *dataptr;
  67. short  length;
  68.  
  69.    {
  70. static     int   leng;
  71. static     short total_tag;
  72. static     long  fdsize;
  73. static     long  next_ifd_ptr;
  74.      long  *ptr;
  75.  
  76. /* if already a list of tags exist, then check if insertion/update */
  77.  
  78.    if (fields_exist)
  79.       {
  80.       tot_tag_num = field_mem_tab[0];
  81.       fdsize = (2+(tot_tag_num * 12));
  82.       leng = (int)fdsize;
  83.       memcpy ( field_mem_tab1, field_mem_tab, leng);
  84.       if (get_tagval(tagnum) <= 0)
  85.  
  86.      {
  87.      if (image_begin)            /* no insertion after image */
  88.      return(0);                /* write*/
  89.  
  90.      field_cur_ptr = (short *) field_mem_tab;
  91.      temp_field_cur_ptr = (short *) field_mem_tab1;
  92.  
  93. /* Check if stripbytcount and stripoffset tags to be included */
  94. /*     check_tag(tagnum, temp_field_cur_ptr);           */
  95.  
  96. /* Build the tag data structure for the specified tag */
  97.  
  98.      if((new_tag_ptr = build_one_tag(filehndl, tagnum, dataptr, fdtype, length)) <= 0)
  99.        return (0);
  100.  
  101. /* Find the position of the tag to be written in the existing field list */
  102.  
  103.      if((new_tag_index = find_tag_pos(tagnum, field_mem_tab1)) < 0)
  104.  
  105.         {
  106.         new_tag_index = field_mem_tab1[0];
  107.         }
  108.  
  109.      new_tag_pos = ((field_mem_tab1 +1) + (new_tag_index * 6));
  110.  
  111.      temp_field_cur_ptr = new_tag_pos;
  112.      new_check_tag(tagnum, temp_field_cur_ptr);
  113.      new_tag_pos = temp_field_cur_ptr;
  114.  
  115. /* Write the new tag data structure into the temp field list */
  116.  
  117.      memcpy( new_tag_pos, new_tag_ptr, bytsize);
  118.  
  119. /* Advance the pointer in the new field buffer */
  120.  
  121.      new_tag_pos += (bytsize/2);
  122.  
  123. /* Append the remaining tags from the original field list to the new list */
  124.  
  125.      if(new_tag_index >= 0)
  126.      {
  127.      if(update_temp_list(field_mem_tab, new_tag_pos, new_tag_index) <= 0)
  128.        return(0);
  129.      }
  130.  
  131. /* Update the total tag number in the new field */
  132.  
  133.      tot_tag_num++;
  134.      field_mem_tab1[0] = (short) tot_tag_num;
  135.      fdsize = (2+(tot_tag_num * 12));
  136.      temp_field_cur_ptr = field_mem_tab1;
  137.      temp_field_cur_ptr += (fdsize/2);
  138.      next_ifd_ptr = 0;
  139.      ptr = (long *) temp_field_cur_ptr;
  140.      *ptr = next_ifd_ptr;
  141.      fdsize +=4;
  142.      leng = (int) fdsize;
  143.  
  144. /* Copy the updated temp field list to the actual field data buffer */
  145.  
  146.      memcpy( field_mem_tab, field_mem_tab1, leng);
  147.  
  148. /* Rewrite the field data, onto the file */
  149.  
  150. /*     field_data_pos = next_val_pos;     */
  151.  
  152.      ifdsize = fdsize;
  153.      if (rewrite_field_data(filehndl) < 0)
  154.       return(0);
  155.  
  156.      field_data_endpos = get_cpos(filehndl);
  157.  
  158. /* Update the first ifd pointer in the header and rewrite the header */
  159.  
  160.      tiff_header.first_ifd_addr = field_data_pos;
  161.      if(header_rewrite(filehndl, header_fil1_pos) < 0)
  162.        return(0);
  163.  
  164.  
  165.      return(1);
  166.  
  167.      }
  168.  
  169. /* The specified tag already exists in the field list, just update the value */
  170.  
  171.       else
  172.  
  173.     {
  174.  
  175.     /* Update the tag value, use old 'write_tag' function */
  176.  
  177.     if(write_tag_val(filehndl, fdtype, tagnum, dataptr, length) <= 0)
  178.       return(0);
  179.  
  180.     return(1);
  181.  
  182.     }
  183.  
  184.       }
  185.  
  186. /* No fields exist, create a new field structure - a new file */
  187.  
  188.    else
  189.  
  190.      {
  191.  
  192.      /* Create new fields with the new header */
  193.  
  194.       fields_exist = 1;
  195.       tot_tag_num = 0;
  196.       ifdsize = 0;
  197.       init_tif_hdr();
  198.       header_fil1_pos = get_cpos(filehndl);
  199.       if (header_write(filehndl) < 0)
  200.      return(0);
  201.  
  202.       next_val_pos = get_cpos(filehndl);
  203.  
  204.       field_cur_ptr = (short *) field_mem_tab;
  205.       build_sbfile_tag(fdtype);
  206.       tot_tag_num++;
  207.       memcpy (&(field_mem_tab[1]), &subfile, sizeof(ifdstrc));
  208.       field_cur_ptr += 7;
  209.  
  210.  
  211.       if ((new_tag_ptr = build_one_tag(filehndl, tagnum, dataptr, fdtype,
  212.                      length)) <= 0)
  213.      return(0);
  214.  
  215.       field_data_pos = next_val_pos;
  216.       tot_tag_num++;
  217.       ifdsize = (2 + (tot_tag_num * 12));
  218.       memcpy(field_cur_ptr, build_tag_mem, bytsize);
  219.       field_mem_tab[0] = (short)tot_tag_num;
  220.       field_cur_ptr = field_mem_tab;
  221.       field_cur_ptr += (ifdsize/2);
  222.       next_ifd_ptr = 0;
  223.       ptr = (long *) field_cur_ptr;
  224.       *ptr = next_ifd_ptr;
  225.       ifdsize += 4;
  226.       if (field_data_write(filehndl, ifdsize) < 0)
  227.      return(0);
  228.       tiff_header.first_ifd_addr = field_data_pos;
  229.       if (header_rewrite(filehndl, header_fil1_pos) < 0)
  230.      return(0);
  231.  
  232.  
  233.  
  234.      return(1);
  235.  
  236.      }
  237.  
  238.    }
  239.  
  240.  
  241. /* --------------------------------------------- */
  242. /*                         */
  243. /* Build one tag data structure in build_tag_mem */
  244. /*                         */
  245. /*    returns: pointer to the buffer         */
  246. /*                         */
  247. /* --------------------------------------------- */
  248.  
  249.  
  250. short  *build_one_tag(filehand, tagno, pointr, filtype, siz_bytes)
  251.  
  252. short    filehand;
  253. short    tagno;
  254. short far  *pointr;
  255. short    filtype;
  256. short siz_bytes;
  257.  
  258.    {
  259.  
  260.    short  *to_ptr;
  261.    short  field_type;
  262.    short  data_length;
  263.    long   field_length, *ptr;
  264.    char   *cptr;
  265.    char far *bptr;
  266.  
  267.    if ((field_type = find_type(tagno)) < 0)
  268.        return((short *)-1);
  269.  
  270.    to_ptr = build_tag_mem;
  271.    *to_ptr++ = tagno;
  272.    *to_ptr++ = field_type;
  273.  
  274.    if((data_length = find_len(field_type)) <= 0)
  275.       return((short *)-1);
  276.  
  277.    field_length = (long) ((siz_bytes + data_length -1)/data_length);
  278.    ptr = (long *) to_ptr;
  279.    *ptr++ = field_length;
  280.    to_ptr = (short *) ptr;
  281.  
  282. /*   if(data_length <= 4)  */
  283.      if(siz_bytes <= 4) 
  284.  
  285.      {
  286.      cptr = (char *) to_ptr;
  287.      bptr = (char far *) pointr;
  288.      while (siz_bytes-- > 0)
  289.        {
  290.        *cptr++ = *bptr++;
  291.        }
  292.      to_ptr = (short *) cptr;
  293.  
  294.      }
  295.  
  296.  
  297.     else
  298.  
  299.      {
  300.  
  301.      if(set_position(filehand, next_val_pos) < 0)
  302.        return(0);
  303.      if (write_data(filehand, pointr, siz_bytes) < 0)
  304.        return(0);
  305.      ptr = (long *) to_ptr;
  306.      *ptr = next_val_pos;
  307.      next_val_pos = get_cpos(filehand);
  308.      field_data_pos = next_val_pos;    /* 9/29 */
  309.      }
  310.  
  311.     return (to_ptr = build_tag_mem);
  312.  
  313.    }
  314.  
  315.  
  316. /* ---------------------------- */
  317. /* Find_len function        */
  318. /* Returns length in bytes for    */
  319. /* the specified field_type    */
  320. /* ---------------------------- */
  321.  
  322. short    find_len(fld_type)
  323.  
  324. short    fld_type;
  325.  
  326.    {
  327.    short data_len;
  328.  
  329.     switch (fld_type)
  330.  
  331.     {
  332.       case 1:
  333.  
  334.       data_len = 1;
  335.       break;
  336.  
  337.       case 2:
  338.  
  339.       data_len = 1;
  340.       break;
  341.  
  342.       case 3:
  343.  
  344.       data_len = 2;
  345.       break;
  346.  
  347.       case 4:
  348.  
  349.       data_len = 4;
  350.       break;
  351.  
  352.       case 5:
  353.  
  354.       data_len = 8;
  355.       break;
  356.  
  357.       default:
  358.  
  359.       data_len = 0;
  360.  
  361.     }
  362.  
  363.    return (data_len);
  364.  
  365.    }
  366.  
  367.  
  368.  
  369.  
  370.  
  371. /* --------------------------------------- */
  372. /*                       */
  373. /* Function:  Find tag position within the */
  374. /*          new field list for the new   */
  375. /*          tag to be inserted       */
  376. /*                       */
  377. /* Return:    Tag position number in the   */
  378. /*          buffer               */
  379. /* --------------------------------------- */
  380.  
  381.  
  382. short    find_tag_pos(tagnmr, field_mem)
  383.  
  384. short    tagnmr;
  385. short    *field_mem;
  386.  
  387.    {
  388.  
  389.    short tag_index = 0;
  390.    short number_of_tags;
  391.    short *field_pointr;
  392.  
  393.    number_of_tags = *field_mem++;
  394.    field_pointr = field_mem;
  395.    while (number_of_tags-- > 0)
  396.      {
  397.      if (tagnmr > *field_pointr)
  398.         {
  399.         field_pointr += 6;
  400.         tag_index += 1;
  401.         }
  402.      else
  403.         {
  404.         return(tag_index);
  405.         }
  406.      }
  407.  
  408.    return (-1);
  409.  
  410.    }
  411.  
  412.  
  413. /* -------------------------------------- */
  414. /* Function: Append the remaining existing*/
  415. /*         tag list to the new tag list */
  416. /*         after the insertion of the   */
  417. /*         new tag.              */
  418. /*                      */
  419. /* Return:   status              */
  420. /*                      */
  421. /* -------------------------------------- */
  422.  
  423.  
  424. short    update_temp_list(exist_field, new_field, tag_index)
  425.  
  426. short    *exist_field;
  427. short    *new_field;
  428. short    tag_index;
  429.  
  430.    {
  431.  
  432.    short *from_ptr;
  433.    short *to_ptr;
  434.    short total_tags;
  435.    short i;
  436.    unsigned bytecount;
  437.  
  438.    total_tags = *exist_field++;
  439.    from_ptr = (exist_field + (tag_index * 6));
  440.    to_ptr = new_field;
  441.    i = (total_tags - (tag_index));         /* because index begins from 0 */
  442.  
  443.    bytecount = (i * 12);
  444.  
  445. /* update the total tag byte count by 12 more bytes */
  446.  
  447.    ifdsize += 12;
  448.  
  449.    memcpy(to_ptr, from_ptr, bytecount);
  450.  
  451.    return(1);
  452.  
  453.    }
  454.  
  455.  
  456.  
  457.  
  458. /*  Check the tag if stripoffset / stripbytecount tags are to be attached */
  459.  
  460. void new_check_tag(tag_num, field_ptr)
  461.    short tag_num;
  462.    short *field_ptr;
  463.  
  464.    {
  465.    void new_build_strpofst_tag(), new_build_strpbytcnt_tag();
  466.  
  467.    if (tag_num > TAG273)
  468.  
  469.      {
  470.      if (tag_273 == 0)
  471.     {
  472.     tag_273 = 1;
  473.     new_build_strpofst_tag(field_ptr);
  474.     }
  475.  
  476.      if (tag_num > TAG279)
  477.  
  478.        {
  479.        if (tag_279 == 0)
  480.      {
  481.      tag_279 = 1;
  482.      new_build_strpbytcnt_tag(temp_field_cur_ptr);
  483.      }
  484.        }
  485.      }
  486.  
  487.    }
  488.  
  489.  
  490. /*  Build stripoffset tag */
  491.  
  492. void new_build_strpofst_tag(field_ptr)
  493.   short *field_ptr;
  494.  
  495.    {
  496.  
  497.      strpofst.tagnum = TAG273;
  498.      strpofst.fieldtype = TLONG;
  499.      strpofst.fieldlen = 0;
  500.      strpofst.offset_rvalue = 0L;
  501.  
  502.      memcpy (field_ptr, &strpofst, sizeof(ifdstrc));
  503.      temp_field_cur_ptr += 6;
  504.      tot_tag_num++;
  505.    }
  506.  
  507.  
  508.  
  509. /*  Build stripbytecount tag */
  510.  
  511. void new_build_strpbytcnt_tag(field_ptr)
  512.    short *field_ptr;
  513.  
  514.  
  515.    {
  516.  
  517.      strpbtcnt.tagnum = TAG279;
  518.      strpbtcnt.fieldtype = TLONG;
  519.      strpbtcnt.fieldlen = 0;
  520.      strpbtcnt.offset_rvalue = 0L;
  521.  
  522.      memcpy (field_ptr, &strpbtcnt, sizeof(ifdstrc));
  523.      temp_field_cur_ptr += 6;
  524.      tot_tag_num++;
  525.    }
  526.